use crate::consts::{BIN_HUGE, LARGE_WSIZE_MAX, PTR_SIZE};
use std::thread::ThreadId;

pub(crate) mod access_guard;
pub(crate) mod atomic_single_linked_list;
pub(crate) mod double_linked_list;
pub(crate) mod os_box;
pub(crate) mod single_linked_list;
mod system_allocator;

#[inline(always)]
pub(crate) fn wsize_from_size(size: usize) -> usize {
    (size + PTR_SIZE - 1) / PTR_SIZE
}

#[inline(always)]
pub(crate) fn bin_from_size(size: usize) -> usize {
    let wsize = wsize_from_size(size);
    if wsize <= 1 {
        return 1;
    }
    if wsize <= PTR_SIZE {
        return (wsize + 1) & !1;
    }
    if wsize > LARGE_WSIZE_MAX {
        return BIN_HUGE;
    }
    let wsize = wsize - 1;
    let b = 31 - (wsize as u32).leading_zeros();
    ((b as usize) << 2) + ((wsize >> (b - 2)) & 0x03) - 3
}

#[macro_export]
macro_rules! debug_println {
    ($($arg:tt)*) => (#[cfg(debug_assertions)] {println!($($arg)*)});
}

#[cfg(not(feature = "multi-thread"))]
pub(crate) fn thread_id() -> ThreadId {
    use std::mem;
    use std::num::NonZeroU64;
    unsafe { mem::transmute(NonZeroU64::new(1).unwrap()) }
}

#[cfg(feature = "multi-thread")]
pub(crate) fn thread_id() -> ThreadId {
    use std::thread;
    thread::current().id()
}
